package com.tianhua.javs.client.model;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * Description:
 * 抽象plantuml 类
 * date: 2021/6/28
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
public abstract class AbstractClassModel {
    /**
     * 类名
     */
    protected String className;

    /**
     * 所在包
     */
    protected String packageName;

    /**
     * 类描述
     */
    protected String classDesc;

    /**
     * 方法
     */
    private List<MethodModel> methodBeanList;

    /**
     * 需要引入的class包名
     */
    private List<String> importClassList;
    /**
     * 属性列表
     *
     */
    private List<FieldModel> fieldBeanList;


    /**
     * 父类方法列表
     */
    private List<MethodModel> superMethodBeanList;

    /**
     * 父类属性列表
     *
     */
    private List<FieldModel> superFieldBeanList;
    /**
     * 实现接口
     */
    private InterfaceModel implInterfaceBean;

    /**
     * 继承类列表
     */
    private String relationClassStr;

    /**
     * 组件名称
     * 根据该标示判断是否是plantUML类图中的还是组件扫描引入的
     */
    private String compName;


    /**
     * bo上的扩展属性对象
     */
    private ExtendFieldBean extendFieldBean = new ExtendFieldBean();


    /**
     * className对应的变量引用名
     *
     */
    private String classVarName;

    /**
     * 是否是springbean
     */
    private boolean springBean;

    public List<MethodModel> getSuperMethodBeanList() {
        return superMethodBeanList;
    }

    public void setSuperMethodBeanList(List<MethodModel> superMethodBeanList) {
        this.superMethodBeanList = superMethodBeanList;
    }

    public List<FieldModel> getSuperFieldBeanList() {
        return superFieldBeanList;
    }

    public void setSuperFieldBeanList(List<FieldModel> superFieldBeanList) {
        this.superFieldBeanList = superFieldBeanList;
    }

    public boolean isSpringBean() {
        return springBean;
    }

    public void setSpringBean(boolean springBean) {
        this.springBean = springBean;
    }

    public String getClassVarIdentifer() {
        if(StringUtils.isEmpty(classVarName)){
            return this.className.substring(0,1).toLowerCase()+this.className.substring(1);
        }
        return classVarName;
    }

    public void setClassVarName(String classVarName) {
        this.classVarName = classVarName;
    }

    public String getClassVarName() {
        return classVarName;
    }

    public String getCompName() {
        return compName;
    }

    public void setCompName(String compName) {
        this.compName = compName;
    }

    public ExtendFieldBean getExtendFieldBean() {
        return extendFieldBean;
    }

    public void setExtendFieldBean(ExtendFieldBean extendFieldBean) {
        this.extendFieldBean = extendFieldBean;
    }


    public String getRelationClassStr() {
        return relationClassStr;
    }

    public void setRelationClassStr(String relationClassStr) {
        this.relationClassStr = relationClassStr;
    }

    public InterfaceModel getImplInterfaceBean() {
        return implInterfaceBean;
    }

    public void setImplInterfaceBean(InterfaceModel implInterfaceBean) {
        this.implInterfaceBean = implInterfaceBean;
    }


    public List<MethodModel> getMethodBeanList() {
        return methodBeanList;
    }

    public void setMethodBeanList(List<MethodModel> methodBeanList) {
        this.methodBeanList = methodBeanList;
    }

    public List<FieldModel> getFieldBeanList() {
        return fieldBeanList;
    }

    public void setFieldBeanList(List<FieldModel> fieldBeanList) {
        this.fieldBeanList = fieldBeanList;
    }

    public List<String> getImportClassList() {
        return importClassList;
    }

    public void setImportClassList(List<String> importClassList) {
        this.importClassList = importClassList;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public String getClassDesc() {
        return classDesc;
    }

    public void setClassDesc(String classDesc) {
        this.classDesc = classDesc;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AbstractClassModel that = (AbstractClassModel) o;
        return Objects.equals(className, that.className) &&
                Objects.equals(packageName, that.packageName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(className, packageName);
    }

    /**
     * 根据一定特征匹配类的方法
     * @param paramType
     * @param returnClassTag
     * @param paramCount
     * @return
     */
    public MethodModel findMethod(String paramType, String returnClassTag, Integer paramCount){
        if(CollectionUtils.isEmpty(methodBeanList)){
            return null;
        }
        for (MethodModel methodModel : methodBeanList){
            Optional<ParamModel> optional = methodModel.getParamModelList().stream().filter(paramModel -> paramModel.getParamType().equals(paramType)).findFirst();
            if(optional.isPresent() && methodModel.getParamModelList().size() == paramCount
                    && methodModel.getReturnClass().toLowerCase().endsWith(returnClassTag.toLowerCase())){
                return methodModel;
            }
        }
        return null;
    }


}
